// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// go:build darwin&&go1。12 
// /+build darwin，go1。12 

package ld

import (
	"syscall"
	"unsafe"
)

// 在syscall包中实现。
// go:linkname fcntl syscall。fcntl 
func fcntl(fd int, cmd int, arg int) (int, error)

func (out *OutBuf) fallocate(size uint64) error {
	stat, err := out.f.Stat()
	if err != nil {
		return err
	}
	// F_peoposmode从文件末尾进行分配，因此我们需要大小差异。显然，它使用分配的结尾，而不是文件的逻辑结尾。
	cursize := uint64(stat.Sys().(*syscall.Stat_t).Blocks * 512) // 分配大小
	if size <= cursize {
		return nil
	}

	store := &syscall.Fstore_t{
		Flags:   syscall.F_ALLOCATEALL,
		Posmode: syscall.F_PEOFPOSMODE,
		Offset:  0,
		Length:  int64(size - cursize),
	}

	_, err = fcntl(int(out.f.Fd()), syscall.F_PREALLOCATE, int(uintptr(unsafe.Pointer(store))))
	return err
}

func (out *OutBuf) purgeSignatureCache() {
	// 显然，达尔文内核可能会将代码签名缓存在mmap中。
	// 当我们映射输出缓冲区时，它没有代码签名
	// （因为我们没有生成一个）。现在
	// 我们已经生成了签名，请使内核缓存无效。见第42684期。尽最大努力。忽略错误。
	syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(&out.buf[0])), uintptr(len(out.buf)), syscall.MS_INVALIDATE)
}
